package com.hzw.saas.service.product.service;

import java.util.Date;
import java.util.Objects;
import javax.annotation.Resource;

import com.hzw.saas.api.hpc.IHpcAccountUserService;
import com.hzw.saas.api.hpc.IHpcItemService;
import com.hzw.saas.api.product.IItemOrderService;
import com.hzw.saas.api.product.IOrderCacheService;
import com.hzw.saas.api.product.dto.*;
import com.hzw.saas.api.product.enums.OrderStatus;
import com.hzw.saas.api.product.enums.OrderType;
import com.hzw.saas.api.product.enums.PayMode;
import com.hzw.saas.common.config.exception.DefaultSaasException;
import com.hzw.saas.common.config.util.RedisUtil;
import com.hzw.saas.common.pay.enums.PayType;
import com.hzw.saas.common.util.IdWorker;
import cn.hutool.core.util.StrUtil;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;

/**
 * 商品订单缓存 实现类
 *
 * @author zzl
 * @since 01/27/2021
 */
@Service("orderCacheServiceImpl")
@RequiredArgsConstructor
public class OrderCacheServiceImpl implements IOrderCacheService {

    private static final String CACHE_NAME = "order";
    private static final long CACHE_TIME = 60 * 60 * 12;
    private final IdWorker idWorker;
    @Resource(name = "hpcItemServiceImpl")
    private IHpcItemService hpcItemService;
    @Resource(name = "hpcAccountUserServiceImpl")
    private IHpcAccountUserService hpcAccountService;
    @Resource(name = "itemOrderServiceImpl")
    private IItemOrderService itemOrderService;

    @Override
    public OrderCacheDto getByOrder(String orderId) {
        return RedisUtil.get(key(orderId));
    }

    @Override
    public OrderCacheDto getByPayNo(String payNo) {
        String orderId = RedisUtil.get(key(payNo));
        if (Objects.isNull(orderId)) {
            return null;
        }
        return RedisUtil.get(key(orderId));
    }

    @Override
    public OrderCacheDto addItemOrder(String userId, String itemId, String hpcAccountId, Integer payType) {
        if (StrUtil.isNotBlank(hpcAccountId)) {
            //验证超算帐号是否属于用户
//            if (!hpcAccountService.verify(userId, hpcAccountId)) {
//                throw DefaultSaasException.build("请求非法，该帐号不属于此用户").status(HttpStatus.FORBIDDEN);
//            }
            // 验证超算帐号是否能购买此商品
            if (!hpcItemService.verify(itemId, hpcAccountId)) {
                throw DefaultSaasException.build("请求非法，该帐号无法购买本商品").status(HttpStatus.FORBIDDEN);
            }
        }

        HpcItemDto hpcItemDto = hpcItemService.get(itemId);
        if (hpcItemDto == null) {
            throw DefaultSaasException.build("商品不存在:" + itemId).status(HttpStatus.BAD_REQUEST);
        }
        // 生成订单缓存
        OrderCacheDto orderCacheDto = new OrderCacheDto();
        PaymentOnlineDto paymentOnlineDto = new PaymentOnlineDto();
        ItemOrderDto itemOrderDto = new ItemOrderDto(hpcItemDto);
        orderCacheDto.setPayment(paymentOnlineDto);
        orderCacheDto.setItemOrder(itemOrderDto);

        String orderId = String.valueOf(idWorker.nextId());
        String payNo = String.valueOf(idWorker.nextId());

        Date now = new Date();
        // payment
        paymentOnlineDto.setPayId(String.valueOf(idWorker.nextId()))
            .setUserId(userId)
            .setOrderId(orderId)
            .setOrderType(OrderType.ITEM.value())
            .setPayNo(payNo)
            .setPayAmount(hpcItemDto.getPriceDiscount() == null || hpcItemDto.getPriceDiscount() == 0 ? hpcItemDto.getPrice() : hpcItemDto.getPriceDiscount())
            .setPayType(payType)
            .setPayTypeText(PayType.text(payType))
            .setPayStatus(OrderStatus.PAY_PROGRESS.value())
            .setPayStatusText(OrderStatus.PAY_PROGRESS.text())
            .setCreateTime(now);

        // itemOrder
        itemOrderDto.setOrderId(orderId)
            .setUserId(userId)
            .setPid(hpcAccountId)
            .setCreateTime(now)
            .setIsPayed(0)
            .setPayMode(PayMode.ONLINE_PAY.value())
            .setPayModeText(PayMode.ONLINE_PAY.text())
            .setStatus(OrderStatus.PAY_PROGRESS.value())
            .setStatusText(OrderStatus.PAY_PROGRESS.text());

        this.add(orderCacheDto);
        return orderCacheDto;
    }

    @Override
    public OrderCacheDto addBalanceOrder(String userId, double payValue, Integer payType) {
        // 生成订单缓存
        OrderCacheDto orderCacheDto = new OrderCacheDto();
        PaymentOnlineDto paymentOnlineDto = new PaymentOnlineDto();
        BalanceOrderDto balanceOrderDto = new BalanceOrderDto();
        orderCacheDto.setPayment(paymentOnlineDto);
        orderCacheDto.setBalanceOrder(balanceOrderDto);

        String orderId = String.valueOf(idWorker.nextId());
        String payNo = String.valueOf(idWorker.nextId());

        Date now = new Date();
        // payment
        paymentOnlineDto.setPayId(String.valueOf(idWorker.nextId()))
            .setUserId(userId)
            .setOrderId(orderId)
            .setOrderType(OrderType.BALANCE.value())
            .setPayNo(payNo)
            .setPayAmount(payValue)
            .setPayType(payType)
            .setPayTypeText(PayType.text(payType))
            .setPayStatus(OrderStatus.PAY_PROGRESS.value())
            .setPayStatusText(OrderStatus.PAY_PROGRESS.text())
            .setCreateTime(now);

        // balanceOrder
        balanceOrderDto.setOrderId(orderId)
            .setUserId(userId)
            .setCreateTime(now)
            .setPayValue(payValue)
            .setIsPayed(0)
            .setPayMode(PayMode.ONLINE_PAY.value())
            .setStatus(OrderStatus.PAY_PROGRESS.value());

        this.add(orderCacheDto);
        return orderCacheDto;
    }

    @Override
    public OrderCacheDto add(OrderCacheDto orderCacheDto) {
        return add(orderCacheDto, CACHE_TIME);
    }

    @Override
    public OrderCacheDto add(OrderCacheDto orderCacheDto, long time) {
        PaymentOnlineDto paymentOnlineDto = orderCacheDto.getPayment();
        RedisUtil.set(key(paymentOnlineDto.getOrderId()), orderCacheDto, time);
        RedisUtil.set(key(paymentOnlineDto.getPayNo()), paymentOnlineDto.getOrderId(), time);
        return orderCacheDto;
    }

    @Override
    public OrderCacheDto deleteByOrder(String orderId) {
        OrderCacheDto orderCacheDto = RedisUtil.get(key(orderId));
        if (orderCacheDto == null) {
            return null;
        }
        RedisUtil.del(key(orderId), key(orderCacheDto.getPayment().getPayNo()));
        return orderCacheDto;
    }

    @Override
    public OrderCacheDto deleteByPayNo(String payNo) {
        String orderId = RedisUtil.get(payNo);
        if (orderId == null) {
            return null;
        }
        OrderCacheDto orderCacheDto = RedisUtil.get(key(orderId));
        RedisUtil.del(key(orderId), key(payNo));
        return orderCacheDto;
    }

    /**
     * 根据cacheName生成key
     *
     * @param key 原始key
     * @return 合成key
     */
    private String key(String key) {
        if (Objects.isNull(key)) {
            return "";
        }
        return CACHE_NAME + "::" + key;
    }
}
